import Foundation

/// Root configuration structure for Peekaboo settings.
/// Test comment for Poltergeist
///
/// This structure represents the complete configuration file format (JSONC) that can be
/// stored at `~/.peekaboo/config.json`. All properties are optional, allowing
/// partial configuration with fallback to environment variables or defaults.
public struct Configuration: Codable {
    public var aiProviders: AIProviderConfig?
    public var defaults: DefaultsConfig?
    public var logging: LoggingConfig?
    public var agent: AgentConfig?
    public var visualizer: VisualizerConfig?
    public var tools: ToolConfig?
    public var customProviders: [String: CustomProvider]?
    public var mcpClients: [String: MCPClientConfig]?
    public var toolDisplay: ToolDisplayConfig?

    public init(
        aiProviders: AIProviderConfig? = nil,
        defaults: DefaultsConfig? = nil,
        logging: LoggingConfig? = nil,
        agent: AgentConfig? = nil,
        visualizer: VisualizerConfig? = nil,
        tools: ToolConfig? = nil,
        customProviders: [String: CustomProvider]? = nil,
        mcpClients: [String: MCPClientConfig]? = nil,
        toolDisplay: ToolDisplayConfig? = nil)
    {
        self.aiProviders = aiProviders
        self.defaults = defaults
        self.logging = logging
        self.agent = agent
        self.visualizer = visualizer
        self.tools = tools
        self.customProviders = customProviders
        self.mcpClients = mcpClients
        self.toolDisplay = toolDisplay
    }

    /// Configuration for AI vision providers.
    ///
    /// Defines which AI providers to use for image analysis, their API keys,
    /// and connection settings. Supports both cloud-based (OpenAI) and local (Ollama) providers.
    public struct AIProviderConfig: Codable {
        public var providers: String?
        public var openaiApiKey: String?
        public var anthropicApiKey: String?
        public var ollamaBaseUrl: String?

        public init(
            providers: String? = nil,
            openaiApiKey: String? = nil,
            anthropicApiKey: String? = nil,
            ollamaBaseUrl: String? = nil)
        {
            self.providers = providers
            self.openaiApiKey = openaiApiKey
            self.anthropicApiKey = anthropicApiKey
            self.ollamaBaseUrl = ollamaBaseUrl
        }
    }

    /// Default settings for screenshot capture operations.
    ///
    /// These settings apply when no command-line arguments are provided,
    /// allowing users to customize their preferred capture behavior.
    public struct DefaultsConfig: Codable {
        public var savePath: String?
        public var imageFormat: String?
        public var captureMode: String?
        public var captureFocus: String?

        public init(
            savePath: String? = nil,
            imageFormat: String? = nil,
            captureMode: String? = nil,
            captureFocus: String? = nil)
        {
            self.savePath = savePath
            self.imageFormat = imageFormat
            self.captureMode = captureMode
            self.captureFocus = captureFocus
        }
    }

    /// Logging configuration for debugging and troubleshooting.
    ///
    /// Controls the verbosity and location of log files generated by Peekaboo
    /// during operation.
    public struct LoggingConfig: Codable {
        public var level: String?
        public var path: String?

        public init(level: String? = nil, path: String? = nil) {
            self.level = level
            self.path = path
        }
    }

    /// Agent configuration for AI-powered automation.
    ///
    /// Controls default settings for the Peekaboo agent, including the AI model
    /// to use and behavior options.
    public struct AgentConfig: Codable {
        public var defaultModel: String?
        public var maxSteps: Int?
        public var showThoughts: Bool?
        public var temperature: Double?
        public var maxTokens: Int?

        public init(
            defaultModel: String? = nil,
            maxSteps: Int? = nil,
            showThoughts: Bool? = nil,
            temperature: Double? = nil,
            maxTokens: Int? = nil)
        {
            self.defaultModel = defaultModel
            self.maxSteps = maxSteps
            self.showThoughts = showThoughts
            self.temperature = temperature
            self.maxTokens = maxTokens
        }
    }

    /// Visualizer configuration for animation and visual feedback.
    ///
    /// Controls visual feedback settings for UI automation operations,
    /// including animations, effects, and individual feature toggles.
    public struct VisualizerConfig: Codable {
        public var enabled: Bool?
        public var animationSpeed: Double?
        public var effectIntensity: Double?
        public var soundEnabled: Bool?
        public var keyboardTheme: String?

        // Individual animation toggles
        public var screenshotFlashEnabled: Bool?
        public var clickAnimationEnabled: Bool?
        public var typeAnimationEnabled: Bool?
        public var scrollAnimationEnabled: Bool?
        public var mouseTrailEnabled: Bool?
        public var swipePathEnabled: Bool?
        public var hotkeyOverlayEnabled: Bool?
        public var appLifecycleEnabled: Bool?
        public var windowOperationEnabled: Bool?
        public var menuNavigationEnabled: Bool?
        public var dialogInteractionEnabled: Bool?
        public var spaceTransitionEnabled: Bool?
        public var ghostEasterEggEnabled: Bool?

        public init(
            enabled: Bool? = nil,
            animationSpeed: Double? = nil,
            effectIntensity: Double? = nil,
            soundEnabled: Bool? = nil,
            keyboardTheme: String? = nil,
            screenshotFlashEnabled: Bool? = nil,
            clickAnimationEnabled: Bool? = nil,
            typeAnimationEnabled: Bool? = nil,
            scrollAnimationEnabled: Bool? = nil,
            mouseTrailEnabled: Bool? = nil,
            swipePathEnabled: Bool? = nil,
            hotkeyOverlayEnabled: Bool? = nil,
            appLifecycleEnabled: Bool? = nil,
            windowOperationEnabled: Bool? = nil,
            menuNavigationEnabled: Bool? = nil,
            dialogInteractionEnabled: Bool? = nil,
            spaceTransitionEnabled: Bool? = nil,
            ghostEasterEggEnabled: Bool? = nil)
        {
            self.enabled = enabled
            self.animationSpeed = animationSpeed
            self.effectIntensity = effectIntensity
            self.soundEnabled = soundEnabled
            self.keyboardTheme = keyboardTheme
            self.screenshotFlashEnabled = screenshotFlashEnabled
            self.clickAnimationEnabled = clickAnimationEnabled
            self.typeAnimationEnabled = typeAnimationEnabled
            self.scrollAnimationEnabled = scrollAnimationEnabled
            self.mouseTrailEnabled = mouseTrailEnabled
            self.swipePathEnabled = swipePathEnabled
            self.hotkeyOverlayEnabled = hotkeyOverlayEnabled
            self.appLifecycleEnabled = appLifecycleEnabled
            self.windowOperationEnabled = windowOperationEnabled
            self.menuNavigationEnabled = menuNavigationEnabled
            self.dialogInteractionEnabled = dialogInteractionEnabled
            self.spaceTransitionEnabled = spaceTransitionEnabled
            self.ghostEasterEggEnabled = ghostEasterEggEnabled
        }
    }

    /// Tool filtering configuration.
    ///
    /// Lets users restrict which tools are exposed to agents and MCP clients.
    /// Both arrays are case-insensitive; names can use `snake_case` or `kebab-case`.
    public struct ToolConfig: Codable {
        public var allow: [String]?
        public var deny: [String]?

        public init(allow: [String]? = nil, deny: [String]? = nil) {
            self.allow = allow
            self.deny = deny
        }
    }

    /// Custom AI provider configuration.
    ///
    /// Defines a custom AI provider endpoint with connection details, supported models,
    /// and capabilities. Allows extending Peekaboo with additional AI services beyond
    /// the built-in providers.
    public struct CustomProvider: Codable {
        public let name: String
        public let description: String?
        public let type: ProviderType
        public let options: ProviderOptions
        public let models: [String: ModelDefinition]?
        public let enabled: Bool

        public init(
            name: String,
            description: String? = nil,
            type: ProviderType,
            options: ProviderOptions,
            models: [String: ModelDefinition]? = nil,
            enabled: Bool = true)
        {
            self.name = name
            self.description = description
            self.type = type
            self.options = options
            self.models = models
            self.enabled = enabled
        }

        /// Provider API compatibility type.
        public enum ProviderType: String, Codable, CaseIterable {
            case openai
            case anthropic

            public var displayName: String {
                switch self {
                case .openai: "OpenAI Compatible"
                case .anthropic: "Anthropic Compatible"
                }
            }
        }
    }

    /// Provider connection and authentication options.
    ///
    /// Contains the technical details needed to connect to a custom provider,
    /// including API endpoint, authentication, and request customization.
    public struct ProviderOptions: Codable {
        public let baseURL: String
        public let apiKey: String // Environment variable reference like {env:API_KEY}
        public let headers: [String: String]?
        public let timeout: TimeInterval?
        public let retryAttempts: Int?
        public let defaultParameters: [String: String]?

        public init(
            baseURL: String,
            apiKey: String,
            headers: [String: String]? = nil,
            timeout: TimeInterval? = nil,
            retryAttempts: Int? = nil,
            defaultParameters: [String: String]? = nil)
        {
            self.baseURL = baseURL
            self.apiKey = apiKey
            self.headers = headers
            self.timeout = timeout
            self.retryAttempts = retryAttempts
            self.defaultParameters = defaultParameters
        }
    }

    /// Model definition with capabilities and constraints.
    ///
    /// Describes an AI model available through a custom provider, including
    /// its capabilities, token limits, and model-specific parameters.
    public struct ModelDefinition: Codable {
        public let name: String
        public let maxTokens: Int?
        public let supportsTools: Bool?
        public let supportsVision: Bool?
        public let parameters: [String: String]?

        public init(
            name: String,
            maxTokens: Int? = nil,
            supportsTools: Bool? = nil,
            supportsVision: Bool? = nil,
            parameters: [String: String]? = nil)
        {
            self.name = name
            self.maxTokens = maxTokens
            self.supportsTools = supportsTools
            self.supportsVision = supportsVision
            self.parameters = parameters
        }
    }

    /// Configuration for MCP client connections to external servers.
    ///
    /// Defines connection parameters for external MCP servers, including transport
    /// type, command execution, environment variables, and connection settings.
    public struct MCPClientConfig: Codable, Sendable {
        public var transport: String
        public var command: String
        public var args: [String]
        public var env: [String: String]
        public var enabled: Bool
        public var timeout: TimeInterval
        public var autoReconnect: Bool
        public var description: String?

        public init(
            transport: String = "stdio",
            command: String,
            args: [String] = [],
            env: [String: String] = [:],
            enabled: Bool = true,
            timeout: TimeInterval = 10.0,
            autoReconnect: Bool = true,
            description: String? = nil)
        {
            self.transport = transport
            self.command = command
            self.args = args
            self.env = env
            self.enabled = enabled
            self.timeout = timeout
            self.autoReconnect = autoReconnect
            self.description = description
        }
    }

    /// Configuration for tool display and organization.
    ///
    /// Controls how tools are shown in listings, including whether to show
    /// external MCP tools by default and how to organize them.
    public struct ToolDisplayConfig: Codable {
        public var showMcpToolsByDefault: Bool
        public var useServerPrefixes: Bool
        public var groupByServer: Bool

        public init(
            showMcpToolsByDefault: Bool = true,
            useServerPrefixes: Bool = true,
            groupByServer: Bool = false)
        {
            self.showMcpToolsByDefault = showMcpToolsByDefault
            self.useServerPrefixes = useServerPrefixes
            self.groupByServer = groupByServer
        }
    }
}
